package com.csii.activiti.server.core.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csii.activiti.server.abstraction.service.ActBasicService;
import com.csii.activiti.server.core.entity.db.ActFlowConfigurationEntity;
import com.csii.activiti.server.core.entity.db.ActFlowGroupEntity;
import com.csii.activiti.server.core.exception.RequestParamException;
import com.csii.activiti.server.core.mapper.ActFlowConfigurationMapper;
import com.csii.activiti.server.core.mapper.ActFlowGroupMapper;
import com.csii.activiti.server.core.service.FlowGroupService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Service
public class FlowGroupServiceImpl extends ServiceImpl<ActFlowGroupMapper, ActFlowGroupEntity> implements FlowGroupService {

    @Autowired
    private ActFlowGroupMapper actFlowGroupMapper;

    @Autowired
    private ActFlowConfigurationMapper actFlowConfigurationMapper;

    @Autowired
    private ActBasicService actBasicService;

    private Map<String,List<ActFlowGroupEntity>> caches;

    private String stopUsingName = "停用";
    private String stopUsingId = "-1";

    @PostConstruct
    private void initCaches(){
        List<ActFlowGroupEntity> actFlowGroupEntities = actFlowGroupMapper.selectList(new LambdaQueryWrapper<ActFlowGroupEntity>().orderByAsc(ActFlowGroupEntity::getSort).orderByDesc(ActFlowGroupEntity::getCreateTime));
        caches = actFlowGroupEntities.stream().collect(Collectors.groupingBy(ActFlowGroupEntity::getActTenantId, ConcurrentHashMap::new,Collectors.toList()));
        //初始化停用数据
        caches.values().forEach(item->item.add(new ActFlowGroupEntity(stopUsingId,stopUsingName,null,null,null)));
    }

    @Override
    public List<ActFlowGroupEntity> queryActFlowGroupList() {
        String currentTenantId = actBasicService.getCurrentTenantId();
        List<ActFlowGroupEntity> actFlowGroupEntities = caches.get(currentTenantId);
        if (actFlowGroupEntities != null){
            return actFlowGroupEntities;
        }
        actFlowGroupEntities = actFlowGroupMapper.selectList(new LambdaQueryWrapper<ActFlowGroupEntity>().eq(ActFlowGroupEntity::getActTenantId, currentTenantId).orderByAsc(ActFlowGroupEntity::getSort).orderByDesc(ActFlowGroupEntity::getCreateTime));
        actFlowGroupEntities.add(new ActFlowGroupEntity(stopUsingId,stopUsingName,null,null,null));
        caches.put(currentTenantId,actFlowGroupEntities);
        return actFlowGroupEntities;
    }

    @Override
    public void editActFlowGroup(ActFlowGroupEntity actFlowGroupEntity) {
        String currentTenantId = actBasicService.getCurrentTenantId();
        Integer count = actFlowGroupMapper.selectCount(new LambdaQueryWrapper<ActFlowGroupEntity>().eq(ActFlowGroupEntity::getGroupName, actFlowGroupEntity.getGroupName()).eq(ActFlowGroupEntity::getActTenantId,currentTenantId).ne(ActFlowGroupEntity::getId, actFlowGroupEntity.getId()));
        if (count> 0){
           throw new RequestParamException("分组名称重复");
        }
        actFlowGroupMapper.updateById(actFlowGroupEntity);
        cleanCaches();
    }

    @Override
    public void deleteActFlowGroup(String id) {
        if (stopUsingId.equals(id)){
            throw new RequestParamException("停用分组不能删除");
        }
        String currentTenantId = actBasicService.getCurrentTenantId();
        Integer count = actFlowConfigurationMapper.selectCount(new LambdaQueryWrapper<ActFlowConfigurationEntity>().eq(ActFlowConfigurationEntity::getGroupId, id).eq(ActFlowConfigurationEntity::getActTenantId,currentTenantId));
        if (count >0){
            throw new RequestParamException("分组下面有流程无法删除");
        }
        actFlowGroupMapper.deleteById(id);
        cleanCaches();
    }

    @Override
    public String addActFlowGroup(ActFlowGroupEntity actFlowGroupEntity) {
        String currentTenantId = actBasicService.getCurrentTenantId();
        Integer count = actFlowGroupMapper.selectCount(new LambdaQueryWrapper<ActFlowGroupEntity>().eq(ActFlowGroupEntity::getGroupName, actFlowGroupEntity.getGroupName()).eq(ActFlowGroupEntity::getActTenantId,currentTenantId));
        if (count> 0){
            throw new RequestParamException("分组名称重复");
        }
        actFlowGroupEntity.setCreateTime(new Date());
        actFlowGroupEntity.setSort(0);
        actFlowGroupEntity.setActTenantId(currentTenantId);
        actFlowGroupMapper.insert(actFlowGroupEntity);
        cleanCaches();
        return actFlowGroupEntity.getId();
    }

    @Override
    public void batchUpdateSort(List<String> ids) {
        List<ActFlowGroupEntity> updateList = ids.stream().map(id -> {
            ActFlowGroupEntity actFlowGroupEntity = new ActFlowGroupEntity();
            actFlowGroupEntity.setId(id);
            return actFlowGroupEntity;
        }).collect(Collectors.toList());
        int sort = 1;
        for (ActFlowGroupEntity actFlowGroupEntity : updateList) {
            actFlowGroupEntity.setSort(sort++);
        }
        updateBatchById(updateList);
        cleanCaches();
    }


    private void cleanCaches(){
        String currentTenantId = actBasicService.getCurrentTenantId();
        caches.remove(currentTenantId);
    }
}
